#include "LogicSystem.h"
#include "LogicNode.h"
#include "Session.h"
#include <json/json.h>

LogicSystem::LogicSystem(int thread_num)
:b_stop_(false)
{
    RegisterCallBack();
    for (size_t i = 0; i < thread_num; i++)
    {
        threads_.emplace_back(&LogicSystem::DealMsg,this);
    }

    
}
LogicSystem::~LogicSystem()
{
    //stop();
}
void LogicSystem::PostMsgToQue(std::shared_ptr<LogicNode> logic_node)
{
    std::unique_lock<std::mutex> lock(mutex_);
    
    //如果停止了逻辑系统停止
    if(b_stop_)
    {
        return;
    }
    msg_que_.push(logic_node);
    if (msg_que_.size() == 1)
    {
        cond_.notify_one();
    }
    
}



void LogicSystem::LogicSystem::DealMsg()
{
    while (!b_stop_)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_.wait(lock,[&](){
            return !msg_que_.empty() || b_stop_;
        });

        //如果停止了逻辑系统停止
        if(b_stop_)
        {
            //处理完队列中剩余的任务
            while(!msg_que_.empty())
            {
                auto logic_node = msg_que_.front();
                msg_que_.pop();

                short msg_id = logic_node->recv_node_->_msg_id;
                auto func_iter = fun_callbacks_.find(msg_id);
                if(func_iter == fun_callbacks_.end())
                {
                    continue;
                }
                func_iter->second(logic_node->session_,msg_id,logic_node->recv_node_->_msg);

            }
            //打印线程退出信息
            std::cout<<"LogicSystem::DealMsg thread id is "<<std::this_thread::get_id()<<" exit"<<std::endl;
            return;
        }
        auto logic_node = msg_que_.front();
        msg_que_.pop();

        short msg_id = logic_node->recv_node_->_msg_id;
        auto func_iter = fun_callbacks_.find(msg_id);

        
        if(func_iter != fun_callbacks_.end())
        {
            func_iter->second(logic_node->session_,msg_id,logic_node->recv_node_->_msg);
        }
    }
    
    
}
void LogicSystem::LogicSystem::RegisterCallBack()
{
    fun_callbacks_[MSG_HELLO_WORLD]=std::bind(&LogicSystem::HelloWorldCallBack,this,
        std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);
}

void LogicSystem::stop()
{
    b_stop_ = true;
    cond_.notify_all();
    for (auto &thread : threads_)
    {
        thread.join();
    }
}



void LogicSystem::HelloWorldCallBack(std::shared_ptr<Session> session,const short &msg_id,const std::string& msg_data)
{
    Json::Reader reader;
    Json::Value root;
    reader.parse(msg_data,root);
    std::cout << "HelloWorldCallBack recevie msg id  is " << root["id"].asInt() << " msg data is "
		<< root["data"].asString() << "\n";
	root["data"] = "server has received msg, msg data is " + root["data"].asString();
    std::string return_str = root.toStyledString();
    session->Send(return_str,root["id"].asInt());
}